Introduction to Software Defined Radios (SDRs) and Its Application Programming Interface

In this tutorial, we will introduce the users with all the APIs that will be used in this course. The APIs are clearly segregated between the input, output and setup functionalities. The tutorial is divided into 3 sub-sections:

  • Import the libraries

  • Setup the SDRs

  • Transmit the samples

  • Receive the samples

Import Python libraries

[1]:

import numpy as np import adi

System Parameters

  • sampleRate: defines the number of samples processed by ADC or DAC for conversion from digital to analog or analog to digital respectively.

  • carrierFrequency: defines the frequency of the carrier for transmission of radio signal.

  • numSamples: defines the sample of samples to buffered for reception in every sniff (or in simple terms receiver buffer size).

[2]:

sampleRate = 10**6 # sample rate for communication carrierFrequency = 985*10**6 # Carrier frequency for radio waves transmission numSamples = 10**5 # number of samples per call to rx()

Set-up the SDR

This code cell setup the SDR for transmission and reception of data.

[6]:
# SDR setup
sdr             = adi.Pluto("ip:192.168.3.1")       # Create object of SDR setup object and configure the IP of SDR connect to the system
sdr.sample_rate = int(sampleRate)                   # Sets the sample rate for the ADC/DAC of the SDR.

# Config Tx
sdr.tx_rf_bandwidth         = int(sampleRate)       # Set the bandwidth of the transmit filter | Can be set same as the sample rate
# For Pluto SDR, tx_rf_bandwidth should be between 200 kHz and 56 MHz.
sdr.tx_lo                   = int(carrierFrequency) # Sets the transmitter local oscillator frequency. The carrier is used to modulate/up-convert the analog information signal.
# For Pluto SDR, tx_lo can take a value between 325 MHz to 3.8 GHz.
sdr.tx_hardwaregain_chan0   = -20                   # Sets the gain (dB) of the transmitter power amplifier. The higher the value the more the power radiated by antenna.
# For Pluto SDR, tx_hardwaregain_chan0 can take values between -90 to 0.

# Config Rx
sdr.rx_lo                   = int(carrierFrequency) # Sets the receiver local oscillator frequency.
# For Pluto SDR, rx_lo can take a value between 325 MHz to 3.8 GHz.
sdr.rx_rf_bandwidth         = int(sampleRate)       # Set the bandwidth (in Hz) of the reception filter
# For Pluto SDR, tx_rf_bandwidth should be between 200 kHz and 56 MHz.
sdr.rx_buffer_size          = 4*numSamples          # Number of samples to read and load into SDR buffer.
# The upper limit on the size of this buffer is defined by the DRAM size.

sdr.gain_control_mode_chan0 = 'manual'              # Defines the mode of receiver AGC.
# It can take one of the 3 values "manual", "slow_attack", "fast_attack". For manual, value has to inputed via `rx_hardwaregain_chan0`
sdr.rx_hardwaregain_chan0   = 30.0 # dB, increase to increase the receive gain, but be careful not to saturate the ADC
# Sets the amplification gain (dB) provided by the low noise amplifier (LNA).
# Relevant only when `gain_control_mode_chan0` is "manual".

Transmitting the data

[7]:
# Create transmit waveform (QPSK, 16 samples per symbol)

x_time = np.random.rand(numSamples) + 1j*np.random.rand(numSamples)

scale         = 2**12       # allows to adjust the range of values to utlize the complete dynamic range of the DAC.

# Start the transmitter
sdr.tx_cyclic_buffer = True # Enable cyclic transmission of samples stored in the transmit buffer.
sdr.tx(scale*x_time)        # start transmitting the input I/Q samples

Receiving the data

[8]:

# Clear the buffer to through away stray data for i in range (0, 15): raw_data = sdr.rx() rx_samples = sdr.rx() # samples the wireless channel using the RF chipset, # stores the samples in the receive buffer, and return the content of the receive buffer. sdr.tx_destroy_buffer() # clear/destroy the transmission buffer and stop the transmission of samples from the tx buffer
[ ]: